package com.edianping.thread;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.LinkedBlockingQueue;

import org.apache.log4j.Logger;

public class ThreadPoolHandle{

	/**
	 * 单位，毫秒。 Idle time to kill if current thread num is bigger than core size
	 * 当然在当前似乎没有效果，因为coresize=maxsize
	 */ 	
	private static long aliveTime = 500l;//500000l;
	private static int poolMaxSize = 7000;
	private BlockingQueue<Runnable> taskQueue = null;

	/**
	 *  临时任务队列,pause 和 resume的时候用
	 */
	private BlockingQueue<Runnable> tempQueue = null;
	private ThreadPoolExecutor pool = null;

	private boolean acceptNew = false;
	public static Logger log = Logger.getLogger(ThreadPoolHandle.class);
	
	public ThreadPoolHandle(int size) {
		
		this.taskQueue = new LinkedBlockingStack<Runnable>();
		pool = new ThreadPoolExecutor(size, size, aliveTime,
				TimeUnit.MILLISECONDS, taskQueue, Executors
						.defaultThreadFactory());
		//下面的这条语句可以在线程池中线程在aliveTime时间内没有新任务的情况下，自动结束线程池的运行，但是，这是jdk1.6的特性，所以呢，使用jdk1.5的时候这句通不过的。		
		//pool.allowCoreThreadTimeOut(true);	
		acceptNew = true;
	}

	
	public void purge()	{
		this.pool.purge();
	}
	
	public int prestartAllCoreThreads(){
		return this.pool.prestartAllCoreThreads();
	}

	/**
	 * @param transactor 将Transactor加入队列
	 */
	public void enqueue( Runnable r )
	{
		if( pool.getQueue().size() >= poolMaxSize) return;
		
		if ( true == acceptNew ){
		    pool.execute( r );
		} 
	}
	

	/*
	 * 删除url所对应的线程
	 * unfinished
	
	public void remove_url(String strUrl)
	{
		Iterator<Runnable> itr = this.pool.getQueue().iterator();
		while(itr.hasNext())
		{
			if( itr.next().getClass()== Transactor.class)
			{
				
			}
		}
		
	} */
	
	/**
	 * 获得当前任务队列的大小
	 * 
	 * @return 当前任务队列的大小
	 */
	public long getCurrentQueueSize() {
		return pool.getQueue().size();
		//+cache.getDiskStoreSize()+cache.getMemoryStoreSize();
	}

	/**
	 * 获得当前线程池中线程的数量
	 * 
	 * @return 当前线程池中线程的数量
	 */
	public int getCurrentPoolSize() {
		return pool.getPoolSize();
	}

	/**
	 * 获得线程池的设置的core Thread的数量
	 * 
	 * @return 线程池的设置的core Thread的数量
	 */
	public int getPoolSize() {
		return pool.getCorePoolSize();
	}

	/**
	 * 更改当前线程池的大小
	 * @param newsize
	 */
	public void setPoolSize(int newsize) {
		if (newsize > 0) {
			pool.setCorePoolSize(newsize);
			pool.setMaximumPoolSize(newsize);
		}
	}

	/**
	 * 暂停线程池的执行,放到临时队列里面去， 还有就是，这个方法不要随便用
	 * 
	 */
	public synchronized void pause() {
		if (tempQueue == null)
			tempQueue = new LinkedBlockingQueue<Runnable>();
		tempQueue.addAll(this.pool.getQueue());
		clearPool();
	}

	/**
	 * 恢复线程池的运行
	 *
	 */
	public synchronized void resume() {
		if (tempQueue != null && !tempQueue.isEmpty()){
			pool.getQueue().addAll(tempQueue);
			tempQueue.clear();
		}
	}

	// hard shutdown
	public void shutdown() {
		this.acceptNew = false;
		this.pool.shutdownNow();
	}

	/**
	 * 清空当前队列，等待一些时间后中止线程池
	 * 注意，请设置足够的时间,让当前执行的线程完成任务，否则这些线程抛出Exception,当然主线程不会收到影响
	 * 
	 * @param seconds:
	 *            等待的时间
	 */
	public void softShundown(int seconds) {
		clearPool();
		try {
			Thread.sleep(seconds * 1000);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			shutdown();
		}
	}
	
	
	public boolean isAlive(){
		return false==pool.isShutdown();
	}
	

	/**
	 * 通常情况下会在执行後几秒钟内结束线程池运行任务 但是线程池本身不会中止运行，还是需要调用<tt>ThreadPoolHandle.shutdown()</tt>
	 * 
	 */
	public void clearPool() {
		//this.pool.getQueue()).clear();
		taskQueue.clear();
	}

	public boolean isAcceptNew() {
		return acceptNew;
	}

	/**
	 * 设定是否接受新的任务
	 * 
	 * @param acceptNew
	 */
	public void setAcceptNew(boolean acceptNew) {
		this.acceptNew = acceptNew;
	}

//	
//	void enqueue(TPoolTestTask task) {
//		pool.execute(task);
//	}
//	
//	/** *************** unit test *********************** */
//
//	public static void main(String[] args) {
//
//    	ThreadPoolHandle handle = new ThreadPoolHandle(2);
//
//    	for (int i = 0; i < 100; i++) {
//			TPoolTestTask task = new TPoolTestTask("hahahha");
//			handle.enqueue(task);
//		}
//		
//		//handle.clearPool();
//		
//		System.out.println(handle.getCurrentQueenSize());
//
//		try {
//			Thread.sleep(2000);
//		} 
//		catch (Exception e) {
//			e.printStackTrace();
//		}
//
//		//handle.pause();
//		System.out.println(handle.getCurrentQueenSize());
//		System.out.println("paused here");
//
//		//handle.resume();
//		
//	}

}